package ru.ifmo.tanya.handler;

import org.apache.log4j.Logger;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import ru.ifmo.tanya.service.HttpService;
import ru.ifmo.tanya.service.impl.*;
import ru.ifmo.tanya.service.mock.*;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ServiceHandler extends AbstractHandler {

    private static final Logger LOG = Logger.getLogger(ServiceHandler.class);
    private static final String X_REAL_IP = "X-Real-IP";

    private Map<String, HttpService> services = new ConcurrentHashMap<String, HttpService>();

    public ServiceHandler() {
        registerService("/service/login", new LoginService());
        registerService("/service/show/hunt/groups", new ShowHuntGroupsService());
        registerService("/service/add/user", new AddUserToGroupsService());
        registerService("/service/remove/user", new RemoveUserFromGroupService());
        registerService("/service/agents/and/queues", new AgentsAndQueuesService());
        registerService("/service/create/call", new CreateCallService());
        registerService("/service/end/call", new EndCallService());
        registerService("/service/log/out", new LogOutServer());
        registerService("/service/mock/answer", new MockAgentAnswerService());
        registerService("/service/show/super/stats", new ShowSuperStatsService());
        registerService("/service/show/call/hist", new ShowCallHistogramService());
    }

    public final void registerService(final String target, final HttpService httpService) {
        services.put(target, httpService);
        LOG.info("Service " + httpService.getClass().getSimpleName() + " registered on target=" + target);
    }

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        HttpService httpService = services.get(target);
        if (httpService == null) {
            LOG.error("No service for target=" + target);
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        String qs = request.getQueryString();
        String ra = request.getRemoteAddr();
        String xRealIp = request.getHeader(X_REAL_IP);
        StringBuilder cookies = new StringBuilder("[");
        final Cookie[] requestCookies = request.getCookies();
        if (requestCookies != null) {
            for (Cookie cookie : requestCookies) {
                cookies.append(cookie.getName()).append("=").append(cookie.getValue()).append(",");
            }
        }
        if(cookies.length() > 0) {
            cookies.deleteCharAt(cookies.length() - 1);
        }
        cookies.append("]");
        LOG.info(httpService.getClass().getSimpleName() +
                " called on " + target + (qs == null ? "" : "?" + qs) +
                ", cookies: " + cookies +
                ", ip: " + (xRealIp == null ? ra : xRealIp));
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        httpService.invoke(request, response);
    }
}
